package com.example.ble_20220504;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.nfc.Tag;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

/**
 * 蓝牙通信类
 */
public class DeviceActivity extends AppCompatActivity {
   //当前所连接的设备
   private BluetoothDevice bluetoothDevice;

    //服务
    private BluetoothGattService bluetoothGattService;

    //读特征
    private BluetoothGattCharacteristic readCharacteristic;

    //写特征
    private BluetoothGattCharacteristic writeCharacteristic;

    //bt_patch(mtu).bin
    public static final String SERVICE_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";  //蓝牙通讯服务
    public static final String READ_UUID = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";  //读特征
    public static final String WRITE_UUID = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";  //写特征 //服务

    //Gatt
    BluetoothGatt bluetoothGatt;

    EditText msg_text;
    Button send_Button;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_device);
        bluetoothDevice =  getIntent().getParcelableExtra("device");
        Log.d(" ", bluetoothDevice.getName());

        //连接设备
        bluetoothGatt = bluetoothDevice.connectGatt(DeviceActivity.this,false,bluetoothGattCallback);
        bluetoothGatt.connect();

        msg_text = (EditText) findViewById(R.id.input_data);
        send_Button = (Button) findViewById(R.id.send_button);

        send_Button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessage(msg_text.getText().toString());
            }
        });

    }

    //操控UI线程
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case BluetoothGatt.GATT_SUCCESS:
                    showMsg("蓝牙连接成功");
                    break;
            }
        }

    };

    /**
     * Toast提示
     */
    private void showMsg(String msg){
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

    //连接回调
    private BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
        @Override
        public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
            super.onPhyUpdate(gatt, txPhy, rxPhy, status);
        }

        @Override
        public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
            super.onPhyRead(gatt, txPhy, rxPhy, status);
        }

        /**
         * 连接状态改变回调
         * @param gatt
         * @param status
         * @param newState
         */
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            switch(status){
                case BluetoothGatt.GATT_SUCCESS:
                    Log.w("连接回调：","BluetoothGatt.GATT_SUCCESS");
                    Message msg = new Message();
                    msg.what = BluetoothGatt.GATT_SUCCESS;
                    mHandler.sendMessage(msg);
                    //连接成功、去发现服务
                    gatt.discoverServices();
                    break;
                case BluetoothGatt.GATT_FAILURE:
                    Log.w("连接回调：","BluetoothGatt.GATT_FAILURE");
                    break;
                case BluetoothGatt.GATT_CONNECTION_CONGESTED:
                    Log.w("连接回调：","BluetoothGatt.GATT_CONNECTION_CONGESTED");
                    break;
                case BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION:
                    Log.w("连接回调：","BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION");
                    break;
                case BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION:
                    Log.w("连接回调：","BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION");
                    break;
                case BluetoothGatt.GATT_INVALID_OFFSET:
                    Log.w("连接回调：","BluetoothGatt.GATT_INVALID_OFFSET");
                    break;
                case BluetoothGatt.GATT_READ_NOT_PERMITTED:
                    Log.w("连接回调：","BluetoothGatt.GATT_READ_NOT_PERMITTED");
                    break;
                case BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED:
                    Log.w("连接回调：","BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED");
                    break;
            }
        }

        /**
         * 发现服务回调
         * @param gatt
         * @param status
         */
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            Log.d("发现服务", "onServicesDiscovered: ");

            //配置服务信息
            for (BluetoothGattService service : gatt.getServices()){
                if (service.getUuid().toString().equals(SERVICE_UUID)){
                    bluetoothGattService = service;
                }
            }

            if (bluetoothGattService == null) {
                //找不到该服务就立即断开连接
                Log.e("", "setupService()-->bluetoothGattService == null");
            }

            //获取读写特征
            for (BluetoothGattCharacteristic characteristic : bluetoothGattService.getCharacteristics()) {
                if (characteristic.getUuid().toString().equals(READ_UUID)) {  //读特征
                    readCharacteristic = characteristic;
                } else if (characteristic.getUuid().toString().equals(WRITE_UUID)) {  //写特征
                    writeCharacteristic = characteristic;
                }
            }

            if (readCharacteristic == null) {
                Log.e("TAG", "setupService()-->readCharacteristic == null");

            }

            if (writeCharacteristic == null) {
                Log.e("TAG", "setupService()-->writeCharacteristic == null");

            }
            //打开读通知
            gatt.setCharacteristicNotification(readCharacteristic,true);

            //重点中重点，需要重新设置
            List<BluetoothGattDescriptor> descriptors = readCharacteristic.getDescriptors();
            for (BluetoothGattDescriptor descriptor : descriptors) {
                descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                gatt.writeDescriptor(descriptor);
            }

        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);

        }

        /**
         * 写入回调
         * @param gatt
         * @param characteristic
         * @param status
         */
        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);
            Log.d("", "写入回调!!");
            if(characteristic.getValue() == null){
                Log.e("TAG","characteristic.getValue() == null");
                return;
            }
            //将收到的字节数组转换成十六进制字符串
            String msg = TypeConversion.bytes2HexString(characteristic.getValue(),characteristic.getValue().length);
            if(status == BluetoothGatt.GATT_SUCCESS){
                //写入成功
                Log.w("TAG","写入成功：" + msg);

            }else if(status == BluetoothGatt.GATT_FAILURE){
                //写入失败
                Log.e("TAG","写入失败：" + msg);
            }else if(status == BluetoothGatt.GATT_WRITE_NOT_PERMITTED){
                //没有权限
                Log.e("TAG","没有权限！");
            }

        }

        /**
         * 接收数据回调
         * @param gatt
         * @param characteristic
         */
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            //接收数据
            byte[] bytes = characteristic.getValue();
            Log.w("TAG","收到数据str:" + TypeConversion.bytes2HexString(bytes,bytes.length));
        }

        @Override
        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorRead(gatt, descriptor, status);
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(gatt, descriptor, status);
        }

        @Override
        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
            super.onReliableWriteCompleted(gatt, status);
        }

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            super.onReadRemoteRssi(gatt, rssi, status);
        }

        @Override
        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
            super.onMtuChanged(gatt, mtu, status);
        }
    };


    ///////////////////////////////////  发送数据  ///////////////////////////////////////////////

    /**
     * 发送消息  byte[]数组
     * @param msg  消息
     * @return  true  false
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public boolean sendMessage(String msg){
        if(writeCharacteristic == null){
            Log.e("","sendMessage(byte[])-->writeGattCharacteristic == null");
            return false;
        }

        if(bluetoothGatt == null){
            Log.e("","sendMessage(byte[])-->mBluetoothGatt == null");
            return false;
        }

        boolean  b = writeCharacteristic.setValue(TypeConversion.hexString2Bytes(msg));
        Log.d("", "写特征设置值结果：" + b);
        return bluetoothGatt.writeCharacteristic(writeCharacteristic);
    }


}